package com.walming.generator.common.utils;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.walming.generator.common.config.JacksonConfig;
import com.walming.generator.common.exception.BusinessException;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * JSON处理工具类
 * </p>
 *
 * @author walming
 * @date 2020-10-01 18:09
 */
public class JsonUtil {

    /**
     * 将Java对象转JSON 字符串
     */
    public static String toJsonString(Object object) {
        return JsonMapper.toJsonString(object);
    }

    /**
     * 将JSON字符串转Java对象
     */
    public static <T> T parseObject(String jsonString, Class<T> clazz) {
        return JsonMapper.toJavaObject(jsonString, clazz);
    }

    /**
     * 将JSON数组字符串转Java对象集合
     */
    public static <T> List<T> parseList(String jsonString, Class<T> clazz) {
        JavaType javaType = JsonMapper.getCollectionType(ArrayList.class, clazz);
        return JsonMapper.toJavaObject(jsonString, javaType);
    }

    /**
     * 将JSON字符串转Map对象
     */
    public static <K, V> Map<K, V> parseHashMap(String jsonString) {
        return JsonMapper.toJavaObject(jsonString, new TypeReference<HashMap<K, V>>() {
        });
    }

    /**
     * 将JSON字符串转JSON对象
     */
    public static JsonNode toJson(String jsonString) {
        return JsonMapper.toJson(jsonString);
    }

    /**
     * 将JAVA对象转JSON对象
     */
    public static JsonNode toJson(Object object) {
        return JsonMapper.toJson(object);
    }

    /**
     * 将JSON字节数组转JSON对象
     */
    public static JsonNode toJson(byte[] jsonBytes) {
        return JsonMapper.toJson(jsonBytes);
    }

    /**
     * 内部类，处理Json
     */
    private static class JsonMapper {

        private static final ObjectMapper OBJECT_MAPPER = JacksonConfig.jacksonObjectMapper();

        /**
         * 获取泛型的Collection Type
         */
        public static JavaType getCollectionType(Class<?> collectionClass, Class<?>... elementClasses) {
            return OBJECT_MAPPER.getTypeFactory().constructParametricType(collectionClass, elementClasses);
        }

        /**
         * JAVA对象转Json符串
         */
        private static String toJsonString(Object object) {
            try {
                return OBJECT_MAPPER.writeValueAsString(object);
            } catch (Exception e) {
                throw new BusinessException("对象转Json失败！", e);
            }
        }

        /**
         * Json字符串转JAVA对象
         */
        private static <T> T toJavaObject(String jsonString, Class<T> clazz) {
            try {
                return OBJECT_MAPPER.readValue(jsonString, clazz);
            } catch (Exception e) {
                throw new BusinessException("Json转对象失败！", e);
            }
        }

        /**
         * Json字符串转JAVA对象
         */
        private static <T> T toJavaObject(String jsonString, TypeReference<T> typeReference) {
            try {
                return OBJECT_MAPPER.readValue(jsonString, typeReference);
            } catch (Exception e) {
                throw new BusinessException("Json转对象失败！", e);
            }
        }

        /**
         * Json字符串转JAVA对象
         */
        private static <T> T toJavaObject(String jsonString, JavaType javaType) {
            try {
                return OBJECT_MAPPER.readValue(jsonString, javaType);
            } catch (Exception e) {
                throw new BusinessException("Json转对象失败！", e);
            }
        }

        /**
         * Json字符串转JSON对象
         */
        private static JsonNode toJson(String jsonString) {
            try {
                return OBJECT_MAPPER.readTree(jsonString);
            } catch (Exception e) {
                throw new BusinessException("Json转对象失败！", e);
            }
        }

        /**
         * Json字符串转JSON对象
         */
        private static JsonNode toJson(byte[] jsonBytes) {
            try {
                return OBJECT_MAPPER.readTree(jsonBytes);
            } catch (Exception e) {
                throw new BusinessException("Json转对象失败！", e);
            }
        }

        /**
         * Json 字符串转JSON 对象
         */
        private static JsonNode toJson(Object object) {
            try {
                return OBJECT_MAPPER.valueToTree(object);
            } catch (Exception e) {
                throw new BusinessException("Json转对象失败！", e);
            }
        }

    }

}
